Chubby作為一個在Google內部各種分散式系統很核心的服務,可惜的是並沒有開源。因此Zookeeper的出現給大家一個更具體的想像這個服務怎麼運作與使用。
因為參考了Chubby的設計,提供的功能也幾乎一樣
但時仍然有很多細部的地方不一樣。
在Chubby中,每一個Node提供了Acquire()
、Release()
的API提供Client加鎖解鎖。
但是Zookeeper的znode並沒有這樣的API,
相反的使用者必須利用基本的API來實作Lock Service
舉例: 假設有一組processes想要搶一個Lock
1. 每一個processes都嘗試創建ephemeral sequential nodes "/data/lock-"
2. 每一個 lock-X 只會創建一次,由ZooKeeper來處理哪一個process創建了哪一個 lock-X (收到請求的時間差)
3. 每一個 process 同時 getChildren 取的 /data 底下所有的 child nodes 並起對 /data znode 設定監聽 watch
4. 規定哪一個 process 有最小的 lock-X 之 X,取得Lock
5. 當他釋放Lock時,就刪除自己的那個e phemeral sequential nodes
6. 其他的processes就會收到事件,這時在看誰是最小就代表拿到Lock -> 回到 3
以上就是最簡單利用Zookeeper實作Lock的方式。
使用到create()、getChildren()、setWatch()即可實作
上述的實作效能很差,因為當process釋放Lock時,Zookeeper必須通知所有的processes。
一種修改的方式就是在第三步
對於processX創建node-X,只setWatch()在node-(X-1)前一個node上。
這樣Zookeeper只要每一次通知下一個process即可。
前面提到Chubby在Caching的部分下了很多苦心
Zookeeper 則是完全沒有設計Cache機制,
提供基礎的API,將這一塊保留給使用者自己開發屬於自己的Cache。
在Chubby裡面是用
正因為每一次讀寫都是從Leader讀,因此不管是讀或是寫都是最高等級的一致性
再藉由Paxos同步更新到其他的replica server
在Zookeeper裡面
搭配Zookeeper的這些API,也可以讓你在自己的分散式系統服務中實作出2PC協定喔~
複習一下2PC
方法:
1. 先用Zookeeper實作出Leader Election,選出coordinator
2. coordinator 創建兩個znode
1. /2PC/transaction/ 和 /2PC/transaction/result
2. setWatch() on /2PC/transaction/
3. 其餘的 participants 則是 setWatch() on /2PC/ and /2PC/transaction/result 兩個znode
4. participants接著在 /2PC/transaction/ 底下創建 ephemeral nodes 並且在自己的 file 寫入 commit/abort 訊息
6. 因為znode /2PC/transaction/ 底下有被更新,所以 coordinator 也會收到事件通知
7. coordinator 接著讀取 participants 創建的 znode 裡面是 commit 還是 abort,並作出統計。
8. coordinator 根據 2PC 協定在/2PC/transaction/result 寫下結果是 rollback 還是 commit
9. participants 也會收到事件通知,此時讀取 /2PC/transaction/result 執行操作後,刪除自己的 ephemeral nodes
今天簡介了Zookeeper與Chubby的差異,並且介紹了如何用Zookeeper實作Lock。
大家可以看到其實創建node這件事情搭配事件通知,
就成了一種分散式系統裡面的通訊方式,
進而實作更複雜的邏輯,甚至是2PC協定。
今天留了一個伏筆,那就是Zookeeper最常見的功能 "Leader Election"
明天將會介紹如何實作,不過聰明的你看完上面兩個例子,
應該可以先想一下,如果是你你會怎麼實作,
其實跟Lock Service實作方式差不多喔~